import * as Cesium from '@cesiumjs';
import {
  G3vObj
} from "@g3xbase"
import * as g3xUtils from "@g3x/utils";
import * as g3vUtils from "@g3v/utils";
import {
  autorun,
  reaction,
  intercept,
  extendObservable,
  computed
} from 'mobx';

/* 50 */
/**
 * 多边形
 * @memberof Obj
 * @class
 * @extends XbsjCzmObj
 */

class G3xPolygon extends G3vObj {

  constructor(viewer, options) {

    super(viewer, options);
    this._pointsColor = [1, 1, 0, 0.95];
    this.init()
  }

  init() {
    const _this = this;
    const {
      disposers,
      viewer
    } = _this;

    disposers.push(g3xUtils.bind(_this, 'enabled', _this, 'show'));

    _this._primitive = undefined;
    disposers.push(function() {
      return _this._primitive && viewer.scene.primitives.remove(_this._primitive);
    });
    _this._groundPrimitive = undefined;
    disposers.push(function() {
      return _this._groundPrimitive && viewer.scene.groundPrimitives.remove(_this._groundPrimitive);
    });

    _this._boundingSphere = new Cesium.BoundingSphere();

    {
      var czmPolygonColor = new (Function.prototype.bind.apply(Cesium.Color, [null,..._this.color]))();
      function updatePolygonPrimitive() {
        czmPolygonColor.xbsjFromArray.apply(czmPolygonColor, _this.color);
        if (_this._primitive) {
          _this._primitive.show = _this.show;
        }

        if (_this._groundPrimitive) {
          _this._groundPrimitive.show = _this.show;
        }
      };

      _this.disposers.push(reaction(function() {
        return {
          color: _this.color,
          show: _this.show
        };
      }, updatePolygonPrimitive));

      function createPolygonPrimitive() {
        _this._primitive && viewer.scene.primitives.remove(_this._primitive);
        _this._primitive = undefined;

        _this._groundPrimitive && viewer.scene.groundPrimitives.remove(_this._groundPrimitive);
        _this._groundPrimitive = undefined;

        if (!_this.ground) {
          var positions = (0, _uniquePolygonPositions2.default)(_this.positions);

          if (positions.length >= 3) {
            var polygonGeometry = new Cesium.PolygonGeometry({
              polygonHierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromRadiansArray(positions)),
              height: _this.height,
              extrudedHeight: _this.extrudedHeight
            });

            var polygonInstance = new Cesium.GeometryInstance({
              geometry: polygonGeometry,
              id: _this
            });

            var primitive = new Cesium.Primitive({
              geometryInstances: [polygonInstance],
              appearance: new Cesium.MaterialAppearance({
                material: Cesium.Material.fromType('Color'),
                faceForward: true,
                renderState: {
                  depthTest: {
                    enabled: _this.depthTest
                    // depthMask: this.depthMask, 设置无效，Appearance内部会强行设置
                  }
                }
              }),
              asynchronous: false, // 防止闪烁
              allowPicking: _this.allowPicking, // 不允许拾取
              compressVertices: false // 提升效率
            });
            primitive.appearance.material.uniforms.color = czmPolygonColor;

            _this._primitive = _this._earth.czm.scene.primitives.add(primitive);
          }
        } else {
          var _positions = (0, _uniquePolygonPositions2.default)(_this.positions);

          if (_positions.length >= 3) {
            var polygonGeometry = new Cesium.PolygonGeometry({
              polygonHierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromRadiansArray(
                _positions)),
              height: _this.height
            });

            var polygonInstance = new Cesium.GeometryInstance({
              geometry: polygonGeometry,
              id: _this
            });

            var groundPrimitive = new Cesium.GroundPrimitive({
              geometryInstances: [polygonInstance],
              appearance: new Cesium.MaterialAppearance({
                material: Cesium.Material.fromType('Color'),
                faceForward: true
              }),
              asynchronous: false, // 防止闪烁
              allowPicking: _this.allowPicking, // 不允许拾取
              compressVertices: false // 提升效率
            });
            groundPrimitive.appearance.material.uniforms.color = czmPolygonColor;

            _this._groundPrimitive = _this._earth.czm.scene.groundPrimitives.add(groundPrimitive);
          }
        }
      };

      var updateBoundingSphere = function updateBoundingSphere() {
        var l = _this.positions.length / 2;
        if (l >= 3) {
          var positionsWithHeight = [];
          for (var i = 0; i < l; ++i) {
            positionsWithHeight.push(_this.positions[i * 2], _this.positions[i * 2 + 1], _this.height);
          }
          var cartesians = Cesium.Cartesian3.fromRadiansArrayHeights(positionsWithHeight);
          _this._boundingSphere = Cesium.BoundingSphere.fromPoints(cartesians, _this._boundingSphere);
        }
      };

      _this.disposers.push((0, _mobx.reaction)(function() {
        return {
          positions: [].concat((0, _toConsumableArray3.default)(_this.positions)),
          height: _this.height,
          extrudedHeight: _this.extrudedHeight,
          ground: _this.ground,
          depthTest: _this.depthTest
        };
      }, function() {
        createPolygonPrimitive();
        updatePolygonPrimitive();
        updateBoundingSphere();
      }));
    }

    _this._polyline = new _Polyline2.default(earth);
    _this.disposers.push(function() {
      return _this._polyline = _this._polyline && _this._polyline.destroy();
    });

    {
      _this._polyline.material.type = 'XbsjColorMaterial';
      _this._polyline.depthTest = _this.depthTest;
      _this._polyline.loop = true;

      (0, _registerPickingParent2.default)(_this._polyline, _this);

      _this.disposers.push((0, _mobx.autorun)(function() {
        _this._polyline.material['XbsjColorMaterial'].color = _this.outline.color;
        _this._polyline.width = _this.outline.width;
        _this._polyline.show = _this.show && _this.outline.show;
        _this._polyline.ground = _this.ground;
        _this._polyline.depthTest = _this.depthTest;
      }));

      {
        var getPolylinePositions = function getPolylinePositions() {
          var l = _this.positions.length / 2;
          var positions = [];
          for (var i = 0; i < l; ++i) {
            positions.push([_this.positions[i * 2], _this.positions[i * 2 + 1], _this.height]);
          }
          return positions;
        };

        var setPolylinePositions = function setPolylinePositions(positions) {
          return _this._polyline && (_this._polyline.positions = positions);
        };
        setPolylinePositions(getPolylinePositions());
        _this.disposers.push((0, _mobx.reaction)(getPolylinePositions, setPolylinePositions));
      }
    }

    /**
     * 是否在三维窗口中编辑
     * @name editing
     * @type {boolean}
     * @instance
     * @default false
     * @memberof Obj.Polygon
     */

    /**
     * 是否在三维窗口中进行点增加的编辑
     * @name creating
     * @type {boolean}
     * @instance
     * @default false
     * @memberof Obj.Polygon
     */

    _this.disposers.push((0, _registerInteractionProperty.registerPolygonCreatingWithHeight)(_this._earth,
      _this, {
        polygonCreatingWithHeight: 'creating'
      }));

    _this.disposers.push((0, _registerInteractionProperty.registerPolygonEditing)(_this._earth, _this, {
      polygonEditingProperty: 'editing'
    }));
    return _this;
  }
}

g3xUtils.g3x_defineClassProperties(G3xPolygon, [{
  key: 'flyTo',
  value: function flyTo() {
    var camera = this._earth.czm.scene.camera;
    camera.flyToBoundingSphere(this._boundingSphere);
  }
}, {
  key: 'destroy',
  value: function destroy() {
    return (0, _get3.default)(Polygon.prototype.__proto__ || (0, _getPrototypeOf2.default)(Polygon
      .prototype), 'destroy', this).call(this);
  }
}, {
  key: 'boundingSphere',
  get: function get() {
    return this._boundingSphere;
  }
}]);

// positions: [],
// height: 0.0,
// show: true,
// color: [1, 1, 0, 0.5],
// showHelper: false,
// outline: {
//     show: true,
//     color: [0, 1, 0, 1],
//     width: 2.0,
// },
// depthTest: false,
// ground: false,

/**
 * 外轮廓属性
 * @class
 * @name Outline
 * @memberof Obj.Polygon
 */

var outlineSchema = {
  title: "Polygon outline Property",
  type: "object",
  properties: {
    /**
     * 是否在三维窗口中显示
     * @type {boolean}
     * @instance
     * @default true
     * @memberof Obj.Polygon.Outline
     */
    show: {
      type: 'boolean',
      title: '是否在三维窗口中显示',
      default: true,
      description: '是否在三维窗口中显示'
    },
    /**
     * 颜色叠加
     * @type {array}
     * @instance
     * @default [0, 1, 0, 1]
     * @memberof Obj.Polygon.Outline
     */
    color: {
      type: 'array',
      items: {
        type: 'number'
      },
      minItems: 4,
      maxItems: 4,
      default: [0, 1, 0, 1],
      description: '颜色叠加'
    },
    /**
     * 线框的宽度
     * @type {number}
     * @instance
     * @default 2.0
     * @memberof Obj.Polygon.Outline
     */
    width: {
      type: 'number',
      title: '线框的宽度',
      default: 2.0,
      description: '线框的宽度'
    }
  }
};

var xbsjSchema = {
  title: "Polygon Property",
  type: "object",
  properties: {
    /**
     * 位置数组，形式如 [2.012, 0.65, 1.9, 0.7, ...] 分别表示 [经度, 纬度, 经度, 纬度, ...]，注意经度纬度以弧度为单位。
     * @type {array}
     * @instance
     * @default true
     * @memberof Obj.Polygon
     */
    positions: {
      type: 'array',
      title: '位置数组',
      default: [],
      description: '位置数组'
    },
    /**
     * 多边形的高度
     * @type {number}
     * @instance
     * @default 0.0
     * @memberof Obj.Polygon
     */
    height: {
      type: 'number',
      title: '多边形的高度',
      default: 0.0,
      description: '多边形的高度'
    },
    /**
     * 多边形的拉伸高度
     * @type {number}
     * @instance
     * @default null
     * @memberof Obj.Polygon
     */
    extrudedHeight: {
      type: 'number',
      title: '多边形的拉伸高度',
      default: null,
      description: '多边形的拉伸高度'
    },
    /**
     * 是否在三维窗口中显示
     * @type {boolean}
     * @instance
     * @default true
     * @memberof Obj.Polygon
     */
    show: {
      type: 'boolean',
      title: '是否在三维窗口中显示',
      default: true,
      description: '是否在三维窗口中显示'
    },
    /**
     * 颜色叠加
     * @type {array}
     * @instance
     * @default [1, 1, 1, 1]
     * @memberof Obj.Polygon
     */
    color: {
      type: 'array',
      items: {
        type: 'number'
      },
      minItems: 4,
      maxItems: 4,
      default: [1, 1, 1, 1],
      description: '颜色叠加'
    },
    /**
     * 是否显示辅助线框
     * @type {boolean}
     * @instance
     * @default false
     * @memberof Obj.Polygon
     */
    showHelper: {
      type: 'boolean',
      title: '是否显示辅助线框',
      default: false,
      description: '是否显示辅助线框'
    },
    /**
     * 外轮廓属性
     * @type {Obj.Polygon.Outline}
     * @instance
     * @memberof Obj.Polygon
     */
    outline: outlineSchema,
    /**
     * 是否开启深度检测
     * @type {boolean}
     * @instance
     * @default false
     * @memberof Obj.Polygon
     */
    depthTest: {
      type: 'boolean',
      title: '是否开启深度检测',
      default: false,
      description: '是否开启深度检测'
    },
    /**
     * 是否贴地
     * @type {boolean}
     * @instance
     * @default true
     * @memberof Obj.Polygon
     */
    ground: {
      type: 'boolean',
      title: '是否贴地',
      default: true,
      description: '是否贴地'
    }
  }
};

G3xPolygon.xbsjSchema = xbsjSchema;

var xbsjClassification = [{
  name: {
    chinese: '通用',
    english: 'General'
  },
  properties: ['positions', 'height', 'show', 'color', 'showHelper', 'outline', 'depthTest', 'ground']
}];

G3xPolygon.xbsjClassification = xbsjClassification;

G3xPolygon.defaultOptions = {
  positions: [],
  height: 0.0,
  extrudedHeight: null,
  show: true,
  color: [1, 1, 0, 0.5],
  showHelper: false,
  outline: {
    show: true,
    color: [0, 1, 0, 1],
    width: 2.0
  },
  depthTest: false,
  ground: false
};

// _XbsjObject2.default.registerType(Polygon, 'Polygon');

export default G3xPolygon;
